Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Objects /
Chapter 7 - View-Related Objects / About View Port Objects


View Port Properties

The interface to view port objects is entirely procedural. You manipulate the information in a view port by modifying its properties using QuickDraw GX functions.

View port objects have nine accessible properties, as shown in Figure 7-2. Note that, because a view port is an object and not a data structure, the order of the properties as shown in Figure 7-2 is completely arbitrary. Properties in italics are references to other objects.

Figure 7-2 View port object properties

These are the accessible properties of a view port:

QuickDraw GX provides functions to manipulate each of these view port object properties.

View Port Clip and Mapping

Like transform objects, view port objects have a clip property and a mapping property. A view port's mapping and clip are applied to a shape after the transform clip and mapping have already been applied.

The clip and mapping properties for a view port follow the same general conventions as for transform objects. The clip property specifies a shape geometry that you use as a mask to restrict the visibility of a shape object when it is displayed or printed. The clip is equivalent to a primitive shape, a shape whose geometry and fill properties by themselves define the shape. Specifically, a clip can be a framed or filled geometric shape, a glyph shape, a 1-bit-per-pixel bitmap shape, or an empty or full shape. Primitive shapes are described in more detail in the geometric operations chapter of Inside Macintosh: QuickDraw GX Graphics.

The filled or framed parts of a view port clip define the areas in which a shape drawn to that view port show through. If the clip shape is a filled rectangle, for example, only the parts of a shape that are within the limits of that rectangle are visible. Commonly, view port clips are filled rectangles, because the visible parts of view ports commonly correspond to rectangular windows or panes of windows.

The mapping property of a view port is a 3 3 matrix that specifies one or more transformations that a view port applies to all shapes drawn into it. You can use the view port mapping to perform operations such as the following:

Most commonly, you use the view port mapping to position the view port (equivalent
to positioning a window), and possibly to scale or rotate its contents. Skewing and perspective are less common, but you can use them for special effects. You can specify the identity mapping, a matrix whose elements have the value 1.0 along the diagonal and 0.0 elsewhere, to leave shapes drawn to this view port unchanged from the application of the transform mapping.

Figure 7-3 shows three different view ports in a single window, all used to display the same shape as that shown in Figure 7-1 on page 7-6. The shape is a vase, and its transform clip causes it to appear as wavy stripes.

Figure 7-3 Clipping and mapping in view ports

In Figure 7-3, each view port's clip shape is a rectangle that defines its pane in the window. The upper left view port uses an identity mapping. The lower left view port's mapping specifies a clockwise rotation. The right view port's mapping specifies scaling (equal in x and y dimensions) that enlarges the shape.

Dither

Dithering is a technique of assigning alternating colors to adjacent pairs or groups of pixels in a device's bitmap to achieve the illusion of a color that cannot be represented directly. For example, if a device only supports three shades of blue, dithering allows QuickDraw GX to assign those colors in a specific order to adjacent pixels, so that the mix of shades in the combined pixels approximates a desired but unsupported shade.

Dithering works one way in shapes that have a uniform color, and another way in bitmaps.

Dithering of Shapes Other Than Bitmaps

The dither property of a view port specifies a dither level, which is the maximum number of colors that QuickDraw GX can use in dithering when it draws a shape. The dither level can be between 1 and 16; a dither level of 1, the simplest, is equivalent to no dithering. A level of 0 is not permitted. Dithering has no effect if the device resolution is 32 bits per pixel.

Table 7-1 shows the pixel patterns that can occur, depending on the dither level. A dither level of 1 provides a solid pattern, which is effectively no dithering. A dither level of 2 provides a 2-by-2 repeating checkerboard pattern. A dither level of 3 provides a 3-by-3 repeating stripe pattern. A dither level of 4 provides a 4-by-2 repeating pattern. Note that the effective resolution of an image decreases as dither level increases, because each set of pixels that make up a unit of the dither pattern function as a single, larger pixel of dithered color.
Table 7-1 Dither levels and patterns
Dither levelAvailable patterns 


1
 graphics/VIE-L-11.jpg 


2


Above patterns, plus:
graphics/VIE-L-38.jpg 


3


Above patterns, plus:
graphics/VIE-L-39.jpg 


4


Above patterns, plus:
graphics/VIE-L-40.jpg 

Implementation Note
Version 1.0 of QuickDraw GX supports a maximum of 16 colors in a dither pattern, although 4 is the practical maximum dither level, especially for grayscale drawing.
QuickDraw GX does not necessarily use exactly the dither pattern specified by the
dither property, unless the ink object attached to the shape drawn to the view port has
its gxForceDitherInk attribute set. For example, if you specify a dither level of 4, QuickDraw GX may use any pattern from level 1 through level 4, as necessary, to
create the illusion of additional colors. If the ink object's gxForceDitherInk
attribute is set, however, only the level-4 pattern is used. Conversely, if the ink
object's gxSuppressDitherInk attribute is set, no dithering occurs. Note also that
you can affect the pixel alignment of the dither pattern with the ink object's gxPortAlignDitherInk attribute. For more information about these ink attributes, see the chapter "Ink Objects" in this book.

QuickDraw GX uses information from the color profile for the view device object to determine the supported colors and it chooses the appropriate colors to use in the dither for you. Although the results of dithering are controlled by the view device, you specify the dither level in the view port object so that you can simulate its effect, on the computer that is running the application, for a device that may not actually be present.

Dithering of Bitmaps

When you draw a bitmap shape, dithering works differently. Unlike with single-color shapes, dithering of bitmaps uses no specific pattern and recognizes no different dither levels. Dithering is off if the dither level is 1, and it is on if the dither level is greater than one.

Dithering of bitmaps uses the process of error diffusion, in which the error (the difference between the computed color of a given pixel and the nearest color available on the view device) is passed to adjacent pixels. The dithering algorithm starts at the top left of the visible part of the bitmap, and progresses through the bitmap, traveling left to right across one row of pixels and then right to left across the next lower row, and so on until the entire bitmap has been traversed. For each pixel, the algorithm adds the accumulated error (passed from the pixel above it and the pixel to the left of it) to the computed color, picks the closest available device color for that pixel, and passes the new error (the new computed color minus the available color) to the pixel to the right and the pixel below; half of the error goes to each.

Not all dither-related ink attributes are applicable to dithering of bitmaps. Setting
or clearing the gxPortAlignDitherInk attribute or the gxForceDitherInk attribute of the ink object attached to a bitmap shape has no effect. Setting the gxSuppressDitherInk attribute, however, does have the effect of turning off dithering, even for bitmaps.

Ink attributes are described in the chapter "Ink Objects" in this book. The bitmap shapes chapter of Inside Macintosh: QuickDraw GX Graphics shows an example of drawing a dithered bitmap.

Drawbacks of Dithering

Dithering can provide good results in many cases, but it does have drawbacks:

Note that dithering and halftones (described next) are mutually exclusive; if you choose both simultaneously, only a halftone is used.

Halftone

A halftone is a pattern of alternating colors of variable intensities in a fixed cell size, used to represent a variety of colors. Halftoning, like dithering, provides a method of representing color by alternating the available colors on view devices that support only a limited number of colors. Unlike a dither pattern, however, a halftone's fixed cell size means that its resolution is constant and adjacent halftones representing different colors mesh well. Also, unlike with dithers, you specify the colors that make up a halftone. If you use halftones, you should be familiar with how QuickDraw GX represents color, as described in the chapter "Color and Color-Related Objects" in this book. Also, note that dithering and halftones are mutually exclusive; if you choose both simultaneously, only a halftone is used.

A halftone consists of a pattern of variable-sized dots of one color against a background of another color. The halftone simulates a desired color (such as a specific intensity of gray), with the proper proportion of dot color (such as black) and background color (such as white). The colors are not limited to single components, however; a halftone can simulate beige, for example, by mixing pink with yellow. QuickDraw GX can attempt to reproduce any desired color by mixing the dot color and background color specified in a halftone. You can specify any color as the background and any other color as the dot color, and QuickDraw GX will find the best mixing proportion, given the specifications that you provide. Commonly, however, if you are using halftones you work with a single color component (such as blue for RGB space or yellow for CMYK space), and you specify that component as the dot color and black (for RGB) or white (for CMYK) as the background color.

A halftone is described by several characteristics, specified in the gxHalftone structure:

struct gxHalftone{
   Fixed          angle;            /* direction of halftone */
   Fixed          frequency;        /* cells per inch */
   gxDotType      method;           /* kind of pattern */
   gxTintType     tinting;          /* tint calculation method*/
   gxColor        dotColor;         /* color of dots */
   gxColor        backgroundColor;  /* color of background */
   gxColorSpace   tintSpace;        /* color space for tint */
};
The angle describes the orientation of the rows of dots in the halftone pattern. It is a fixed-point number between 0.0 and 360.0 that describes an angle, in degrees, clockwise from horizontal. Figure 7-4 shows several angles.

Figure 7-4 Halftone angle

Each cell in a halftone is an area that contains some proportion of background color and dot color. The frequency describes the size of the cells, in terms of numbers of dots per inch. You typically specify a frequency based on desired output quality and device resolution. Figure 7-5 shows examples of various frequencies.

Figure 7-5 Halftone frequency

The method, or dot type, describes the halftone pattern itself and how it is filled: the shapes of the dots, the pattern of their arrangement, and the way in which a dot fills its cell as it enlarges. The supported methods are defined in the gxDotTypes enumeration:

enum gxDotTypes{
   gxRoundDot = 1,
   gxSpiralDot,
   gxSquareDot,
   gxLineDot,
   gxEllipticDot,
   gxTriangleDot,
   gxDispersedDot
};

typedef long gxDotType;
Figure 7-6 shows examples of these patterns.

Figure 7-6 Halftone dot types

The tinting, or tint type, specifies how the input color (the original color to which the halftone is applied) is to be approximated by a ratio of dot color and background color. The tint is a calculated value from zero to one: if the tint is zero, the halftone is composed only of the background color (the dots are infinitesimally small); if the tint is one, the halftone is composed entirely of the dot color (the dots fill their cells entirely). The tint color is the actual color represented by the combination of dot and background, and is therefore a weighted average of the dot color and background color. The tint color may be only an approximation to--or even just a single component of--the input color. The gxTintTypes enumeration, described on page 7-67, defines these tinting choices:

The dot color and background color are, respectively, the color of the dots and the color of the background used to form the halftone. In the halftone structure, they are full color specifications, not just single color-component values. In setting up a halftone structure, you need to specify these colors in a way that is meaningful considering the tint type you have chosen. For example, if you are creating a halftoned color separation, you typically use a dot color that is the same color as the color component specified in the tint type, and a background color of white.

The tint space describes the color space the input color is converted to before the tint value is determined. For instance, you can set the tint space to CMYK space to separate out the cyan portion of an image that may have been created in RGB space. It is not necessary for the input colors or the view device colors to be set to CMYK space, only the halftone.

Note that halftoning occurs for a shape only if its view port contains a valid halftone structure, and if its ink object's gxSuppressHalftoneInk attribute is cleared. The gxSuppressHalftoneInk attribute is described in the chapter "Ink Objects" in this book.

Parent and Child View Ports

Two view port properties, the parent view port and the child view port list, allow you to arrange view ports in a hierarchy. The primary advantage of this capability is that QuickDraw GX manages the positional relationships among several related view ports for you.

In a view port object, the hierarchical relationship is represented by parent and child view port references. Each view port can reference one parent view port and any number of child view ports. When you move a view port by altering its clip and mapping, QuickDraw GX moves all its child view ports (and their child view ports, if any) accordingly. If the parent view port of your view port is attached to a window, QuickDraw GX moves your view port (and its children) to match movements of the parent whenever the user moves the window.

A view port hierarchy consists of a root view port, which is one with no parent view port, and all of its child view ports. If a child view port is also a parent view port, its children are part of the hierarchy too, and so on. Any parent view port in a hierarchy also defines a subhierarchy that consists of itself as the root, its child view ports, their child view ports, and so on.

Consider, for example, the window shown in Figure 7-7. Like in Figure 7-3 on page 7-10, it displays three different views of a vase. In this case, however, all the views are scrollable, which requires four view ports in a hierarchy.

Figure 7-7 Hierarchical view ports in a window

The four view ports associated with the window in Figure 7-7 are arranged in the simple hierarchy shown in Figure 7-8.

Figure 7-8 A view port hierarchy

View port A encompasses the entire content area of the window. It does not have a parent, so it is the root of the hierarchy. View port A has three child view ports: B, C,
and D. View ports B, C, and D all have the same parent, view port A. None of them, however, have child view ports of their own.

This hierarchial organization allows QuickDraw GX to automatically move all view ports when the window is moved. It also allows you to support scrolling in view port B, C, or D with minimal effort. When the user scrolls pane B, for example, the translation in view port B's mapping is changed to reflect the shape's new position in the window. No changes are required to the other child view ports or to view port A to implement scrolling. See the section "View Port Objects and Windows" beginning on page 7-21 for more information on view port hierarchies and windows.

When you set up a view port hierarchy, you create the root view port by calling the GXNewWindowViewPort function if you want the view port to be associated with a window, or the GXNewViewPort function otherwise. You create child view ports by calling the GXNewViewPort function for each, and then using the GXSetViewPortParent and GXSetViewPortChildren functions to organize them into a hierarchy.

The following rules apply when you set up a view port hierarchy:

View Port Attributes

Each view port object has a set of attributes, a group of flags that specify different aspects of display behavior. View port attributes allow you to specify drawing in gray only, to constrain shapes to integral pixel locations, or to enable color matching for shapes drawn to the port. Table 7-2 lists the constants for the view port attribute and describes what each one means. The constants are defined in the gxPortAttributes enumeration.
View port attributes
ConstantValueExplanation
gxGrayPort0x0001If set, QuickDraw GX only allows grays to be drawn to the view port; it converts colors into a gray color space. Color spaces are described in the chapter "Color and Color-Related Objects" in this book.
gxAlwaysGridPort0x0002If set, QuickDraw GX sets the gxDeviceGridStyle style attribute for all shapes drawn to the view port. This has the effect of constraining a shape to integral pixel values, thus avoiding distortion due to rounding of fractional coordinates. For more information about the gxDeviceGridStyle attribute, see the geometric styles chapter of Inside Macintosh: QuickDraw GX Graphics.
gxEnableMatchPort0x0004If set, QuickDraw GX performs color matching for all shapes drawn to this view port. Note that you must set this attribute for color matching to occur; color matching is off by default in view ports. Color matching is described in the chapter "Color and Color-Related Objects" in this book.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996